<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>


    <script>
        // 函数的元,函数的参数个数
        // 什么是偏函数 partial Application
        // 在计算机科学中,偏函数叫做部分应用,局部应用
        // 指固定一个函数的一些参数,然后产生另一个更小元的函数


        // 偏函数和柯里化的区别
        // 柯里化:将一个多参数的函数转换成多个单参数的函数;将n元函数转换成n个一元函数
        // 偏函数:是固定一个函数的一个或多个参数;将n元函数转换成n-x元的函数

        function add(a, b, c, d) {
            return a + b + c + d;
        }
        Function.prototype.partial = function() {
            var _self = this,
                _args = [].slice.call(arguments);
            return function() {
                var newArgs = _args.concat([].slice.call(arguments));
                return _self.apply(this, newArgs)
            }
        }
        var newAdd = add.partial(1, 2);
        console.log(newAdd(3, 4));

        // 惰性函数
        var timeStamp = null;
        // 不是纯函数,有副作用
        // 重复执行if
        function getTimgeStamp() {
            if (timeStamp) {
                console.log('if');
                return timeStamp
            }
            console.log(1);
            timeStamp = new Date().getTime();
            return timeStamp
        }
        //程序依然每次执行
        var getTimgeStamp1 = (function() {
            // console.log('getTimgeStamp1');
            var timeStamp = new Date().getTime();
            return function() {
                return timeStamp
            }
        })()

        //惰性函数
        // 惰性函数表示函数执行的分支只会在函数第一次调用的时候执行,
        // 在第一次调用的过程中,该函数被覆盖为另一个按照合适的方式执行的函数
        // 这样任何对原函数的调用就不用在经过执行的分支
        var getTimgeStamp2 = function() {
            var timeStamp = new Date().getTime();
            console.log('1');
            getTimgeStamp2 = function() {
                console.log(2);
                return timeStamp
            }
            return getTimgeStamp2()
        }
        console.log(getTimgeStamp2());
        console.log(getTimgeStamp2());
        console.log(getTimgeStamp2());
        console.log(getTimgeStamp2());
        console.log('---------------');
        console.log(getTimgeStamp1());
        console.log(getTimgeStamp1());
        console.log(getTimgeStamp1());
        console.log(getTimgeStamp1());

        console.log(getTimgeStamp());
        console.log(getTimgeStamp());
        console.log(getTimgeStamp());
        console.log(getTimgeStamp());

        var addEvent = function(el, type, fn, capture) {
            if (el.addEventListrner) {
                addEvent = function(el, type, fn, capture) {
                    el.addEventListrner(type, fn, capture)
                }
            } else if (el.attachEvent) {
                addEvent = function(el, type, fn) {
                    el.attachEvent('on' + type, function() {
                        fn.call(el)
                    })
                }
            } else {
                addEvent = function(el, type, fn) {
                    el['on' + type] = fn
                }
            }
        }
    </script>
</body>

</html>